//============================================================================================
/**
 * @file	hurdle_poke_icon.c
 * @brief	ポケスロン競技：ハードル走　ポケモンアイコン
 * @author	Nozomu Saito
 */
//============================================================================================

#include "hurdle_poke_icon.h"

#include "system/arc_util.h"
#include "system/clact_tool.h"

#include "poketool/pokeicon.h"
#include "poketool/poke_tool.h"

#include "hurdle_obj_pri.h"

#include "pkthev_dash.naix"

#define POKE_ICON_MAX (12)			//ポケモンアイコン表示数

// ポケモンアイコンが始まるVRAM上でのオフセット
#define POKEICON_VRAM_OFFSET	(16*0x20)		//障害物競走キャラの後ろから(1D256Kモードなので、8キャラアライメント)
//ポケモンアイコンサイズ
#define POKEICON_TRANS_CHARA	(4*4)
//アイコン転送サイズ
#define POKEICON_TRANS_SIZE		(POKEICON_TRANS_CHARA*0x20)
// ポケモンアイコンのパレットを転送するオフセット
#define POKEICON_PAL_OFFSET		( 3 )	//障害物競走OBJパレット、ジャンプエフェクトパレット、マーカパレットがこのまえにマッピングされる

#define	ICON_RES_CODE	(128)		//かぶらない適当な値

#define ICON_DEF_Y	(16-2)

#define RANKER_ANM_OFS	(16)		//セル依存

typedef struct HURDLE_POKE_ICON_tag
{
	CLACT_WORK_PTR ClactIcon;
	CLACT_WORK_PTR ClactMarker;
	CLACT_WORK_PTR ClactRanker;
	int PosX;
}HURDLE_POKE_ICON;

typedef struct HURDLE_POKE_ICON_CNT_tag
{
	int HeapID;
	// セルアクター関連
	CLACT_SET_PTR	ClactSet;				// セルアクターセット
	CLACT_U_EASYRENDER_DATA RendData;			// 簡易レンダーデータ
	CLACT_U_RES_MANAGER_PTR ResMan[CLACT_U_RES_MAX];	// リソースマネージャ
	CLACT_U_RES_OBJ_PTR ResObjTbl[CLACT_U_RES_MAX];	// リソースオブジェテーブル
	CLACT_HEADER ClActHeader;
	//アイコン
	HURDLE_POKE_ICON Icon[POKE_ICON_MAX];
}HURDLE_POKE_ICON_CNT;

static void InitCellActor(HPI_CNT_PTR ptr);
static void MakeCellActorHeader(HPI_CNT_PTR ptr);
static void SetPokemonIcon(HPI_CNT_PTR ptr, const ICON_INFO *inIconInfo);
static void MakeCLACT_ADD(CLACT_ADD *add, HPI_CNT_PTR ptr, CLACT_HEADER *header, int param);

//--------------------------------------------------------------------------------------------
/**
 * 初期化
 *
 * @param	inHeapID			ヒープID
 *
 * @return	HURDLE_POKE_ICON_PTR	アイコンポインタ
 */
//--------------------------------------------------------------------------------------------
HPI_CNT_PTR HurdlePokeIcon_Alloc(const int inHeapID)
{
	HPI_CNT_PTR ptr;
	int size;
	size = sizeof(HURDLE_POKE_ICON_CNT);
	ptr = sys_AllocMemory(inHeapID, size);
	MI_CpuClearFast( ptr, size);

	ptr->HeapID = inHeapID;

	return ptr;
}

//--------------------------------------------------------------------------------------------
/**
 * 解放
 *
 * @param	ptr			管理ポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void HurdlePokeIcon_Free(HPI_CNT_PTR ptr)
{
	//アクター削除
	int i;
	//ポケモンアイコン
	for(i = 0; i < POKE_ICON_MAX; i++){
		CLACT_Delete(ptr->Icon[i].ClactIcon);
		CLACT_Delete(ptr->Icon[i].ClactMarker);
		CLACT_Delete(ptr->Icon[i].ClactRanker);
	}

	// キャラ転送マネージャー破棄
	CLACT_U_CharManagerDelete(ptr->ResObjTbl[CLACT_U_CHAR_RES]);
	// パレット転送マネージャー破棄
	CLACT_U_PlttManagerDelete(ptr->ResObjTbl[CLACT_U_PLTT_RES]);

	// キャラ・パレット・セル・セルアニメのリソースマネージャー破棄
	for(i=0;i<CLACT_U_RES_MAX;i++){
		CLACT_U_ResManagerDelete(ptr->ResMan[i]);
	}

	// セルアクターセット破棄
	CLACT_DestSet(ptr->ClactSet);

	sys_FreeMemoryEz(ptr);
}

//--------------------------------------------------------------------------------------------
/**
 * セットアップ
 *
 * @param	ptr			管理ポインタ
 * @param	inMonsNo	アイコン情報配列
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void HurdlePokeIcon_Setup(HPI_CNT_PTR ptr, const ICON_INFO *inIconInfo)
{
	InitCellActor(ptr);
	MakeCellActorHeader(ptr);
	SetPokemonIcon(ptr, inIconInfo);
	CLACT_U_SetSubSurfaceMatrix( &ptr->RendData, 0, 0 );
	CLACT_U_SetMainSurfaceMatrix( &ptr->RendData, 0, (192*FX32_ONE) );
}

//--------------------------------------------------------------------------------------------
/**
 * 座標セット
 *
 * @param	ptr			管理ポインタ
 * @param	inIndex		インデックス
 * @param	inPos		位置
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void HurdlePokeIcon_SetPosition(HPI_CNT_PTR ptr, const int inIndex, const int inPos)
{
	VecFx32 vec;
	vec.z = 0;
	vec.x = FX32_ONE * inPos;
	vec.y = FX32_ONE * ICON_DEF_Y;
	CLACT_SetMatrix(ptr->Icon[inIndex].ClactIcon, &vec);
	CLACT_SetMatrix(ptr->Icon[inIndex].ClactMarker, &vec);
	CLACT_SetMatrix(ptr->Icon[inIndex].ClactRanker, &vec);
}

//--------------------------------------------------------------------------------------------
/**
 * 順位セット
 *
 * @param	ptr			管理ポインタ
 * @param	inIndex		インデックス
 * @param	inRank		順位
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void HurdlePokeIcon_SetRank(HPI_CNT_PTR ptr, const int inIndex, const u8 inRank)
{
	GF_ASSERT((0<inRank)&&(inRank<=RANK_DISP_MAX));
	CLACT_AnmChg( ptr->Icon[inIndex].ClactRanker, RANKER_ANM_OFS+inRank-1 );
}

//--------------------------------------------------------------------------------------------
/**
 * 全アイコンの表示・非表示
 *
 * @param	ptr		管理ポインタ
 * @param	inFlg	表示：1	非表示：0
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void HurdlePokeIcon_SetAllVanish(HPI_CNT_PTR ptr, const int inFlg)
{
	int i;
	for(i=0;i<POKE_ICON_MAX;i++){
		CLACT_SetDrawFlag(ptr->Icon[i].ClactIcon, inFlg);
		CLACT_SetDrawFlag(ptr->Icon[i].ClactMarker, inFlg);
///		CLACT_SetDrawFlag(ptr->Icon[i].ClactRanker, inFlg);ランカーは常に表示
	}
}

//--------------------------------------------------------------------------------------------
/**
 * 指定アイコンの表示・非表示
 *
 * @param	ptr		管理ポインタ
 * @param	inIndex インデックス
 * @param	inFlg	表示：1	非表示：0
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void HurdlePokeIcon_SetVanish(HPI_CNT_PTR ptr, const int inIndex, const int inFlg)
{
	CLACT_SetDrawFlag(ptr->Icon[inIndex].ClactIcon, inFlg);
	CLACT_SetDrawFlag(ptr->Icon[inIndex].ClactMarker, inFlg);
	CLACT_SetDrawFlag(ptr->Icon[inIndex].ClactRanker, inFlg);
}

//--------------------------------------------------------------------------------------------
/**
 * 指定アイコンとマーカのプライオリティ変更
 *
 * @param	ptr		管理ポインタ
 * @param	inIndex インデックス
 * @param	inPri	プライオリティ	0〜11
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void HurdlePokeIcon_SetPri(HPI_CNT_PTR ptr, const int inIndex, const u8 inPri)
{
	u8 mark_pri;
	u8 icon_pri;

	GF_ASSERT(inPri < POKE_ICON_MAX);

	icon_pri = PRI_POKE_ICON + (inPri*2);
	mark_pri = PRI_POKE_ICON + (inPri*2+1);
	CLACT_DrawPriorityChg( ptr->Icon[inIndex].ClactIcon, icon_pri );
	CLACT_DrawPriorityChg( ptr->Icon[inIndex].ClactMarker, mark_pri );
	CLACT_DrawPriorityChg( ptr->Icon[inIndex].ClactRanker, PRI_RANKER );
}


//--------------------------------------------------------------------------------------------
/**
 * 描画
 *
 * @param	ptr		管理ポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void HurdlePokeIcon_Draw(HPI_CNT_PTR ptr)
{
	CLACT_Draw( ptr->ClactSet );
}

//------------------------------------------------------------------
/**
 * @brief	セルアクターの初期化
 * @param	ptr		管理ポインタ
 * @return	NONE
 */
//------------------------------------------------------------------
static void InitCellActor(HPI_CNT_PTR ptr)
{
	int i;
	// セルアクター初期化(アイコン12+マーカ12+順位マーク12)
	ptr->ClactSet = CLACT_U_SetEasyInit( POKE_ICON_MAX*3, &ptr->RendData, ptr->HeapID);

	//リソースマネージャー初期化
	for(i=0;i<CLACT_U_RES_MAX;i++){	//リソースマネージャー作成
		ptr->ResMan[i] = CLACT_U_ResManagerInit(1, i, ptr->HeapID);
	}

	//---------上画面用-------------------
	//chara読み込み
	ptr->ResObjTbl[CLACT_U_CHAR_RES] =
		CLACT_U_ResManagerResAddArcChar(ptr->ResMan[CLACT_U_CHAR_RES],
					    ARC_PKTHEV_DASH, NARC_pkthev_dash_CharacterIcon_NCGR,
					    FALSE, ICON_RES_CODE, NNS_G2D_VRAM_TYPE_2DSUB, ptr->HeapID);

	//pal読み込み
	ptr->ResObjTbl[CLACT_U_PLTT_RES] =
		CLACT_U_ResManagerResAddArcPltt(ptr->ResMan[CLACT_U_PLTT_RES],
					    ARC_PKTHEV_DASH, NARC_pkthev_dash_ColorIcon_NCLR,
					    FALSE, ICON_RES_CODE, NNS_G2D_VRAM_TYPE_2DSUB, 1, ptr->HeapID);	//<<ダミーで送っておく

	//cell読み込み
	ptr->ResObjTbl[CLACT_U_CELL_RES] =
		CLACT_U_ResManagerResAddArcKindCell(ptr->ResMan[CLACT_U_CELL_RES],
						ARC_PKTHEV_DASH, NARC_pkthev_dash_CellIcon_NCER,
						FALSE, ICON_RES_CODE, CLACT_U_CELL_RES,ptr->HeapID);

	//同じ関数でanim読み込み
	ptr->ResObjTbl[CLACT_U_CELLANM_RES] =
		CLACT_U_ResManagerResAddArcKindCell(ptr->ResMan[CLACT_U_CELLANM_RES],
						ARC_PKTHEV_DASH, NARC_pkthev_dash_CellIcon_NANR,
						FALSE, ICON_RES_CODE, CLACT_U_CELLANM_RES,ptr->HeapID);
	// Chara転送
	CLACT_U_CharManagerSetAreaCont( ptr->ResObjTbl[CLACT_U_CHAR_RES] );
	// パレット転送
	CLACT_U_PlttManagerSet( ptr->ResObjTbl[CLACT_U_PLTT_RES] );

	// ポケモンアイコン用パレットを一気に読み込んでVRAM転送する
	ArcUtil_PalSet( ARC_POKEICON, PokeIconPalArcIndexGet(), PALTYPE_SUB_OBJ, POKEICON_PAL_OFFSET*0x20,
			  0, ptr->HeapID);

}

//------------------------------------------------------------------
/**
 * @brief	セルアクターヘッダの作成
 * @param	ptr			管理ポインタ
 * @return	NONE
 */
//------------------------------------------------------------------
static void MakeCellActorHeader(HPI_CNT_PTR ptr)
{
	// セルアクターヘッダ作成
	CLACT_U_MakeHeader(	&ptr->ClActHeader,
						ICON_RES_CODE, ICON_RES_CODE, ICON_RES_CODE, ICON_RES_CODE,
						CLACT_U_HEADER_DATA_NONE, CLACT_U_HEADER_DATA_NONE,
			     0, 0,
			     ptr->ResMan[CLACT_U_CHAR_RES],
				 ptr->ResMan[CLACT_U_PLTT_RES],
			     ptr->ResMan[CLACT_U_CELL_RES],
				 ptr->ResMan[CLACT_U_CELLANM_RES],
			     NULL,NULL);
}

//------------------------------------------------------------------
/**
 * @brief	ポケモンアイコンセット
 * @param	ptr				管理ポインタ
 * @param	inIconInfo 		作るアイコン情報
 * @return	NONE
 */
//------------------------------------------------------------------
static void SetPokemonIcon(HPI_CNT_PTR ptr, const ICON_INFO *inIconInfo)
{
	int index;
	CLACT_ADD add;

//	u8 char_buf[POKEICON_TRANS_SIZE];	// キャラクタバッファ
	u8 pal_no;
	u32 arc_index;
	ARCHANDLE* handle;
	void *buf;

	int adrs;

	handle = ArchiveDataHandleOpen( ARC_POKEICON, ptr->HeapID);
	buf = sys_AllocMemoryLo(ptr->HeapID, 4096);

	MakeCLACT_ADD(&add, ptr, &ptr->ClActHeader, NNS_G2D_VRAM_TYPE_2DSUB );

	for(index=0;index<POKE_ICON_MAX;index++){
		NNSG2dCharacterData *chara;
		int mons_no;
		u8 form;
		// ポケモンのアイコン登録
		ptr->Icon[index].ClactIcon = CLACT_Add(&add);
		CLACT_SetAnmFlag(ptr->Icon[index].ClactIcon, 1);
		CLACT_AnmChg( ptr->Icon[index].ClactIcon, index );
		//マーカの登録
		ptr->Icon[index].ClactMarker = CLACT_Add(&add);
		CLACT_AnmChg( ptr->Icon[index].ClactMarker, POKE_ICON_MAX+(index/3) );
		//順位マークの登録
		ptr->Icon[index].ClactRanker = CLACT_Add(&add);
		if (index<RANK_DISP_MAX){
			CLACT_AnmChg( ptr->Icon[index].ClactRanker, RANKER_ANM_OFS+index );
		}
		adrs = POKEICON_VRAM_OFFSET + POKEICON_TRANS_SIZE*index;
		mons_no = inIconInfo[index].MonsNo;
		form = inIconInfo[index].Form;
		//未設定は消す
		if (!mons_no){
			CLACT_SetDrawFlag( ptr->Icon[index].ClactIcon, 0 );
			CLACT_SetDrawFlag( ptr->Icon[index].ClactMarker, 0 );
			CLACT_SetDrawFlag( ptr->Icon[index].ClactRanker, 0 );
		}

		//プライオリティ
		CLACT_DrawPriorityChg( ptr->Icon[index].ClactIcon, PRI_POKE_ICON );
		CLACT_DrawPriorityChg( ptr->Icon[index].ClactMarker, PRI_MARKER );
		CLACT_DrawPriorityChg( ptr->Icon[index].ClactRanker, PRI_RANKER );

		//座標セット
		{
			int disp = ICON_HALF_SIZE + (ICON_HALF_SIZE * 2 * index);
			HurdlePokeIcon_SetPosition(ptr, index, disp);
		}

		//ランカーははじめから表示
		CLACT_SetDrawFlag(ptr->Icon[index].ClactRanker, 1);

		// ポケモンのデータインデックス番号を取得
		arc_index = PokeIconCgxArcIndexGetByMonsNumber( mons_no, 0, form );
		// ポケモンキャラクタをバッファに転送
		ArchiveDataLoadByHandle(handle, arc_index, buf);
		NNS_G2dGetUnpackedBGCharacterData( buf, &chara );
		//パレット
		pal_no = PokeIconPalNumGet( mons_no, form, 0 )+POKEICON_PAL_OFFSET;

		// キャラクター転送
		DC_FlushRange(chara->pRawData, POKEICON_TRANS_SIZE);
		GXS_LoadOBJ(chara->pRawData, adrs, POKEICON_TRANS_SIZE);
		// パレット設定
		CLACT_PaletteNoChg(ptr->Icon[index].ClactIcon, pal_no);

	}
	sys_FreeMemoryEz(buf);
	ArchiveDataHandleClose( handle );
}

//------------------------------------------------------------------
/**
 * @brief	CLACT_ADDの雛形を作成
 * @param	add		セルアクターADD構造体へのポインタ
 * @param	ptr		管理ポインタ
 * @param	header	アクターヘッダー
 * @param	param	描画エリア
 * @return	NONE
 */
//------------------------------------------------------------------
static void MakeCLACT_ADD(CLACT_ADD *add, HPI_CNT_PTR ptr, CLACT_HEADER *header, int param)
{
  add->ClActSet		= ptr->ClactSet;
  add->ClActHeader	= &ptr->ClActHeader;
  add->mat.x		= FX32_ONE*(256-16);
  add->mat.y		= FX32_ONE*(ICON_DEF_Y);
  add->mat.z		= 0;
  add->sca.x		= FX32_ONE;
  add->sca.y		= FX32_ONE;
  add->sca.z		= FX32_ONE;
  add->rot		= 0;
  add->pri		= PRI_POKE_ICON;
  add->DrawArea		= param;
  add->heap		= ptr->HeapID;
}